package citation.data; /** * This is a class to retrieve real ticket numbers * and ask for more if you need more */ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import javax.microedition.io.Connector; import javax.microedition.io.file.FileConnection; import citation.extra.ExtraStringUtils; import net.rim.device.api.io.FileInputStream; import net.rim.device.api.io.FileOutputStream; import net.rim.device.api.util.Persistable; /** * A mostly Abstract(some state to make things easier * and for a primitive lock) Class for fetching a unique ticket number * it reads a file, takes the first number and returns that as ticket num * If the ticket file has less then fewTickets be it asks the database for more(not implemented yet * It also has a function to ask for more tickets if needed from outside of getting unique ticket count * (Useful for running when your Application gets a network connection, if your phone frequently doesn't have one.) */ public class TicketNumberHandler{ private String[] usableTicketNumbers; private int fewTickets=100;//Used to tell if you need more tickets private static boolean locked=false;//simple lock to prevent timing issues /*** * Simple Lock to make sure this and checkNumberOfTicketsandWrite * don't run at the same time, I think it would simply wait for the other to complete * @return A unique ticket number or -1 on error * */ public int getUniqueTicketNumber(){ try{ while(locked) this.wait(1); }catch(InterruptedException badlock){ return -1; } locked=true; readCurrentTickets(); checkIfRunningLowOnTickets(1); writeTicketsFromMemoryMinusHead(); locked=false; return head(); } /** * Again with the simple lock, this version is used * outside of getting tickets * @return true if enough tickets, or you were able to get more,false otherwise */ public boolean checkNumberOfTicketsandWrite(){//version for calling from outside getUniqueTicketNumber when trying to add tickets (if needed while we have a network). try{ while(locked) this.wait(1); }catch(InterruptedException badlock){ return false; } boolean tempBool=true; locked=true; tempBool=checkIfRunningLowOnTickets(0); locked=false; return tempBool; } /* * return true if good-don't need more tickets or got more tickets,false otherwise */ private boolean checkIfRunningLowOnTickets(int cutoff) { if (usableTicketNumbers.length< fewTickets) return checkoutTicketBook(cutoff); else return true; } /** * read tickets and store in class ticket storage array */ private void readCurrentTickets() { try { FolderCreateIfItDoesntExist("file:///store/home/user/Cite"); FileConnection ticketFile = FileOpenForReading("file:///store/home/user/Cite/ticketFile"); if(ticketFile!=null) { usableTicketNumbers=readTicketsFromFileReturnStringArray(ticketFile); ticketFile.delete(); } } catch (IOException e) { } } /** * Put back all tickets back into the file except head(used ticket) */ private void writeTicketsFromMemoryMinusHead() { try{ FileConnection ticketTempFile = FileOpenForWriting("file:///store/home/user/Cite/ticketTempFile"); WriteStringArrayToFile(usableTicketNumbers,ticketTempFile); FileConnection ticketfile = (FileConnection)Connector.open("file:///store/home/user/Cite/ticketFile"); if(ticketfile.exists()) { ticketfile.delete(); ticketfile.close(); } ticketTempFile.rename("file:///store/home/user/Cite/ticketFile"); ticketTempFile.close(); } catch(IOException e){ } } /** * @return head of ticket string list as int */ private int head(){ if(usableTicketNumbers.length>0) return Integer.parseInt(usableTicketNumbers[0]); else return -1;//failure } /** * The actual hard work of reading in the tickets as bytes and making an array of strings(that hold integers in string form) * @param tf = fileconnection * @return array of strings * @throws IOException */ private String[] readTicketsFromFileReturnStringArray(FileConnection tf) throws IOException { InputStream readticketFile=tf.openInputStream(); ByteArrayOutputStream holdBytes=new ByteArrayOutputStream(); byte arr[]= new byte[1024]; while(readticketFile.read(arr,0,1024)>0){//need to check how this function works!!!!! holdBytes.write(arr,0,1024); } String temp[]=ExtraStringUtils.split(holdBytes.toString(),' '); holdBytes.flush();//are both flush and close needed? holdBytes.close(); readticketFile.close(); return temp; } /** * * @param strings=array to write back to file * @param wfile=file connection * @throws UnsupportedEncodingException * @throws IOException */ private void WriteStringArrayToFile(String[] strings,FileConnection wfile) throws UnsupportedEncodingException, IOException { if(wfile!=null) { OutputStream writeTemp=wfile.openOutputStream(); for(int i=1;i<usableTicketNumbers.length;i++) writeTemp.write(usableTicketNumbers[i].getBytes("UTF-8")); writeTemp.flush(); writeTemp.close(); } } private boolean checkoutTicketBook(int cutoff) { return addTicketsToArray(askServerForNewTicketBook(),cutoff); } /** * unimplemented * @return Array of strings (ints) or null if it didn't work */ private String [] askServerForNewTicketBook() { return null;//Needs Implementing } /** * * @param Ticketbook array to add to array held by class * @param cutoff, not used probably a mistake, get rid of it. * @return true if Ticketbook is not null */ private boolean addTicketsToArray(String[] Ticketbook,int cutoff) { if(Ticketbook!=null) { String checkout[]={"Stub"}; String temparray[]=new String[checkout.length+usableTicketNumbers.length]; int i,j=0; for(i=0;i<usableTicketNumbers.length;i++) temparray[i]=usableTicketNumbers[i]; for(j=0;j<checkout.length;j++) temparray[i+j]=checkout[j]; usableTicketNumbers=temparray; return true; } else return false; } /** * Make sure we are working on existing directory by making it if it doesn't exist * @param FolderPath * @throws IOException */ public void FolderCreateIfItDoesntExist(String FolderPath) throws IOException { FileConnection ticketFolder = (FileConnection)Connector.open("FolderPath"); if (!ticketFolder.exists()) ticketFolder.mkdir(); ticketFolder.close(); } /* * Returns null if the file doesn't exist,since you don't need to read an empty file */ public FileConnection FileOpenForReading(String FilePath) throws IOException { FileConnection fc=null; fc = (FileConnection)Connector.open(FilePath); if (!fc.exists()) { fc.close(); return null; } return (FileConnection)Connector.open(FilePath); } /* * Creates file if it doesn't exist, returns null if it can't create it. */ public FileConnection FileOpenForWriting(String FilePath) throws IOException { try{ FileConnection fc=null; fc = (FileConnection)Connector.open(FilePath); if (!fc.exists()) { fc.create(); } return fc; }catch(IOException ProblemOpeningFile){ return null; } } }